﻿namespace PerpetuumSoft.InstrumentationPDA
{
    using PerpetuumSoft.InstrumentationPDA.Mathematics;
    using System;
    using System.Drawing;

    public abstract class LinearControl : ValuePresenter
    {
        private int barWidth = 8;
        private int indent = 0x10;
        private string[] labels = new string[0];
        private SliderElementsPosition labelsPosition = SliderElementsPosition.TopLeft;
        private PerpetuumSoft.InstrumentationPDA.Orientation orientation = PerpetuumSoft.InstrumentationPDA.Orientation.Horizontal;
        private bool reverseScale;
        private int scaleDivisions = 10;
        private int scaleLabelDivisions = 4;
        private int scaleSubDivisions = 5;
        private int scaleWidth = 20;
        private ColorSection[] sectionColors = new ColorSection[] { new ColorSection(Color.Black, 60M), new ColorSection(Color.SaddleBrown, 80M), new ColorSection(Color.Red, 100M) };
        private int ticksLenght = 8;
        private SliderElementsPosition ticksPosition = SliderElementsPosition.Both;
        private Color valueBackgroundColor = Color.Transparent;
        private SliderElementsPosition valuePosition = SliderElementsPosition.BottomRight;

        protected LinearControl()
        {
        }

        protected virtual void DrawCurrentValue(Graphics g)
        {
            if (this.ValuePosition != SliderElementsPosition.None)
            {
                string text = base.Value.ToString(base.Format);
                this.DrawText(g, base.ValueToPercent(base.Value), text, this.ValuePosition, this.ValueBackgroundColor);
            }
        }

        protected override void DrawDynamic(Graphics g)
        {
            this.DrawCurrentValue(g);
        }

        private void DrawLine(Graphics g, Color c, Vector v1, Vector v2, Vector v3, Vector v4)
        {
            if ((this.ticksPosition == SliderElementsPosition.TopLeft) || (this.ticksPosition == SliderElementsPosition.Both))
            {
                g.DrawLine(new Pen(c), (int) Math.Round(v1.X, 0), (int) Math.Round(v1.Y, 0), (int) Math.Round(v2.X, 0), (int) Math.Round(v2.Y, 0));
            }
            if ((this.ticksPosition == SliderElementsPosition.BottomRight) || (this.ticksPosition == SliderElementsPosition.Both))
            {
                g.DrawLine(new Pen(c), (int) Math.Round(v4.X, 0), (int) Math.Round(v4.Y, 0), (int) Math.Round(v3.X, 0), (int) Math.Round(v3.Y, 0));
            }
        }

        protected virtual void DrawScale(Graphics g)
        {
            if (this.TicksPosition != SliderElementsPosition.None)
            {
                for (int i = 0; i <= this.ScaleDivisions; i++)
                {
                    Vector vector = this.FromPoint(i / this.ScaleDivisions);
                    Vector vector2 = new Vector(this.Direction, vector.X, (vector.Y - this.TicksLenght) - (this.ScaleWidth / 2));
                    Vector vector3 = new Vector(this.Direction, vector.X, vector.Y - (this.ScaleWidth / 2));
                    Vector vector4 = new Vector(this.Direction, vector.X, vector.Y + (this.ScaleWidth / 2));
                    Vector vector5 = new Vector(this.Direction, vector.X, (vector.Y + this.TicksLenght) + (this.ScaleWidth / 2));
                    this.DrawLine(g, this.GetColor((i * 100) / this.ScaleDivisions), vector2, vector3, vector4, vector5);
                    if (i != this.ScaleDivisions)
                    {
                        for (int j = 1; j < this.ScaleSubDivisions; j++)
                        {
                            decimal num3 = (i / this.ScaleDivisions) + ((j / this.ScaleSubDivisions) / this.ScaleDivisions);
                            Vector vector6 = this.FromPoint(num3);
                            Vector vector7 = new Vector(this.Direction, vector6.X, (vector6.Y - (this.TicksLenght / 2)) - (this.ScaleWidth / 2));
                            Vector vector8 = new Vector(this.Direction, vector6.X, vector6.Y - (this.ScaleWidth / 2));
                            Vector vector9 = new Vector(this.Direction, vector6.X, vector6.Y + (this.ScaleWidth / 2));
                            Vector vector10 = new Vector(this.Direction, vector6.X, (vector6.Y + (this.TicksLenght / 2)) + (this.ScaleWidth / 2));
                            this.DrawLine(g, this.GetColor(num3 * 100M), vector7, vector8, vector9, vector10);
                        }
                    }
                }
            }
            if (this.labelsPosition != SliderElementsPosition.None)
            {
                int num4;
                bool flag = false;
                if (this.labels != null)
                {
                    for (num4 = 0; num4 < this.labels.Length; num4++)
                    {
                        if ((this.labels[num4] != string.Empty) && (this.labels[num4] != null))
                        {
                            flag = true;
                            break;
                        }
                    }
                }
                int num5 = flag ? (this.labels.Length - 1) : this.ScaleLabelDivisions;
                for (num4 = 0; num4 <= num5; num4++)
                {
                    string text = base.FormatValue(base.PercentToValue((num5 != 0) ? (num4 / num5) : 0.5M));
                    if (flag)
                    {
                        text = this.labels[num4];
                    }
                    new Vector(g.MeasureString(text, this.Font).ToSize());
                    this.DrawText(g, (num5 != 0) ? (num4 / num5) : 0.5M, text, this.LabelsPosition, Color.Transparent);
                }
            }
        }

        protected override void DrawStatic(Graphics g)
        {
            this.DrawScale(g);
        }

        private void DrawText(Graphics g, decimal k, string text, SliderElementsPosition position, Color color)
        {
            Color color2 = this.GetColor(k * 100M);
            Vector vector = new Vector(g.MeasureString(text, this.Font).ToSize());
            Vector vector2 = this.FromPoint(k);
            Vector vector3 = new Vector(this.Direction, vector2.X - (vector[this.Direction] / 2M), (((vector2.Y - (((this.TicksPosition == SliderElementsPosition.Both) || (this.TicksPosition == SliderElementsPosition.TopLeft)) ? this.TicksLenght : 0)) - (this.ScaleWidth / 2)) - 2M) - vector.GetSecondaryValue(this.Direction));
            Vector vector4 = new Vector(this.Direction, vector2.X - (vector[this.Direction] / 2M), ((vector2.Y + (((this.TicksPosition == SliderElementsPosition.Both) || (this.TicksPosition == SliderElementsPosition.BottomRight)) ? this.TicksLenght : 0)) + (this.ScaleWidth / 2)) + 2M);
            if ((position == SliderElementsPosition.TopLeft) || (position == SliderElementsPosition.Both))
            {
                if (color != Color.Transparent)
                {
                    g.FillRectangle(new SolidBrush(color), base.Round(vector3.X), base.Round(vector3.Y), base.Round(vector.Width), base.Round(vector.Height));
                }
                g.DrawString(text, this.Font, new SolidBrush(color2), (float) base.Round(vector3.X), (float) base.Round(vector3.Y));
            }
            if ((position == SliderElementsPosition.BottomRight) || (position == SliderElementsPosition.Both))
            {
                if (color != Color.Transparent)
                {
                    g.FillRectangle(new SolidBrush(color), base.Round(vector4.X), base.Round(vector4.Y), base.Round(vector.Width), base.Round(vector.Height));
                }
                g.DrawString(text, this.Font, new SolidBrush(color2), (float) base.Round(vector4.X), (float) base.Round(vector4.Y));
            }
            if (position == SliderElementsPosition.Internal)
            {
                vector3 = new Vector(vector2[this.Direction] - (vector.Width / 2M), vector2.GetSecondaryValue(this.Direction) - (vector.Height / 2M));
                if (color != Color.Transparent)
                {
                    g.FillRectangle(new SolidBrush(color), base.Round(vector3.X), base.Round(vector3.Y), base.Round(vector.Width), base.Round(vector.Height));
                }
                g.DrawString(text, this.Font, new SolidBrush(color2), (float) base.Round(vector3.X), (float) base.Round(vector3.Y));
            }
        }

        protected Vector FromPoint(decimal value)
        {
            return new Vector(this.ToPoint(base.PercentToValue(value))[this.Direction], this.ToPoint(base.PercentToValue(value)).GetSecondaryValue(this.Direction));
        }

        protected virtual Color GetColor(decimal curentValue)
        {
            foreach (ColorSection section in this.SectionsColors)
            {
                if (section.MaximumPercent >= curentValue)
                {
                    return section.Color;
                }
            }
            return Color.Black;
        }

        protected override Vector ToPoint(decimal value)
        {
            return (this.StartPoint + ((Vector) ((this.EndPoint - this.StartPoint) * base.ValueToPercent(value))));
        }

        protected override decimal ToValue(Vector v)
        {
            return base.PercentToValue((v[this.Direction] - this.StartPoint[this.Direction]) / (this.EndPoint[this.Direction] - this.StartPoint[this.Direction]));
        }

        public int BarWidth
        {
            get
            {
                return this.barWidth;
            }
            set
            {
                if (this.barWidth != value)
                {
                    this.barWidth = value;
                    base.InvalidateStatic();
                }
            }
        }

        protected int CenterLine
        {
            get
            {
                Vector vector = new Vector(this.WorkRectangle.X, this.WorkRectangle.Y);
                Vector vector2 = new Vector(this.WorkRectangle.Width, this.WorkRectangle.Height);
                decimal num = (vector2.GetSecondaryValue(this.Direction) / 2M) + vector.GetSecondaryValue(this.Direction);
                bool flag = (this.LabelsPosition == SliderElementsPosition.BottomRight) && (((this.ValuePosition == SliderElementsPosition.BottomRight) || (this.ValuePosition == SliderElementsPosition.None)) || (this.ValuePosition == SliderElementsPosition.Internal));
                bool flag2 = (this.LabelsPosition == SliderElementsPosition.TopLeft) && (((this.ValuePosition == SliderElementsPosition.TopLeft) || (this.ValuePosition == SliderElementsPosition.None)) || (this.ValuePosition == SliderElementsPosition.Internal));
                if (flag)
                {
                    num = (4M + (this.BarWidth / 2)) + vector.GetSecondaryValue(this.Direction);
                    if ((this.TicksPosition == SliderElementsPosition.TopLeft) || (this.TicksPosition == SliderElementsPosition.Both))
                    {
                        num += this.TicksLenght + 4;
                    }
                }
                else if (flag2)
                {
                    num = ((vector2.GetSecondaryValue(this.Direction) - (this.BarWidth / 2)) - 4M) + vector.GetSecondaryValue(this.Direction);
                    if ((this.TicksPosition == SliderElementsPosition.BottomRight) || (this.TicksPosition == SliderElementsPosition.Both))
                    {
                        num -= this.TicksLenght + 4;
                    }
                }
                return base.Round(num);
            }
        }

        protected PerpetuumSoft.InstrumentationPDA.Mathematics.Direction Direction
        {
            get
            {
                if (this.Orientation == PerpetuumSoft.InstrumentationPDA.Orientation.Horizontal)
                {
                    return PerpetuumSoft.InstrumentationPDA.Mathematics.Direction.X;
                }
                return PerpetuumSoft.InstrumentationPDA.Mathematics.Direction.Y;
            }
        }

        protected Vector EndPoint
        {
            get
            {
                Vector vector = new Vector(this.WorkRectangle.X, this.WorkRectangle.Y);
                if (this.ReverseScale)
                {
                    return new Vector(this.Direction, this.indent + vector[this.Direction], this.CenterLine);
                }
                Vector vector2 = new Vector(base.Size);
                return new Vector(this.Direction, (vector2[this.Direction] - this.indent) - vector[this.Direction], this.CenterLine);
            }
        }

        public int Indent
        {
            get
            {
                return this.indent;
            }
            set
            {
                if (value != this.indent)
                {
                    this.indent = value;
                    base.InvalidateStatic();
                }
            }
        }

        public string[] Labels
        {
            get
            {
                return this.labels;
            }
            set
            {
                if (value == null)
                {
                    value = new string[0];
                }
                this.labels = value;
                base.InvalidateStatic();
            }
        }

        public SliderElementsPosition LabelsPosition
        {
            get
            {
                return this.labelsPosition;
            }
            set
            {
                if (value == SliderElementsPosition.Internal)
                {
                    value = SliderElementsPosition.Both;
                }
                if (this.labelsPosition != value)
                {
                    this.labelsPosition = value;
                    base.InvalidateStatic();
                }
            }
        }

        public PerpetuumSoft.InstrumentationPDA.Orientation Orientation
        {
            get
            {
                return this.orientation;
            }
            set
            {
                if (value != this.orientation)
                {
                    this.orientation = value;
                    base.InvalidateStatic();
                }
            }
        }

        public bool ReverseScale
        {
            get
            {
                return this.reverseScale;
            }
            set
            {
                if (value != this.reverseScale)
                {
                    this.reverseScale = value;
                    base.InvalidateStatic();
                }
            }
        }

        public int ScaleDivisions
        {
            get
            {
                return this.scaleDivisions;
            }
            set
            {
                if ((this.scaleDivisions != value) && (value > 0))
                {
                    this.scaleDivisions = value;
                    base.InvalidateStatic();
                }
            }
        }

        public int ScaleLabelDivisions
        {
            get
            {
                return this.scaleLabelDivisions;
            }
            set
            {
                if ((value != this.scaleLabelDivisions) && (value > 0))
                {
                    this.scaleLabelDivisions = value;
                    base.InvalidateStatic();
                }
            }
        }

        public int ScaleSubDivisions
        {
            get
            {
                return this.scaleSubDivisions;
            }
            set
            {
                if (value != this.scaleSubDivisions)
                {
                    this.scaleSubDivisions = value;
                    base.InvalidateStatic();
                }
            }
        }

        public int ScaleWidth
        {
            get
            {
                return this.scaleWidth;
            }
            set
            {
                if (this.scaleWidth != value)
                {
                    this.scaleWidth = value;
                    base.InvalidateStatic();
                }
            }
        }

        public ColorSection[] SectionsColors
        {
            get
            {
                return this.sectionColors;
            }
            set
            {
                if ((value == null) || (value.Length == 0))
                {
                    value = new ColorSection[] { new ColorSection(Color.Black, 100M) };
                }
                this.sectionColors = value;
                base.InvalidateStatic();
            }
        }

        protected Vector StartPoint
        {
            get
            {
                Vector vector = new Vector(this.WorkRectangle.X, this.WorkRectangle.Y);
                if (this.ReverseScale)
                {
                    Vector vector2 = new Vector(base.Size);
                    return new Vector(this.Direction, (vector2[this.Direction] - this.indent) - vector[this.Direction], this.CenterLine);
                }
                return new Vector(this.Direction, this.indent + vector[this.Direction], this.CenterLine);
            }
        }

        public int TicksLenght
        {
            get
            {
                return this.ticksLenght;
            }
            set
            {
                if (value != this.ticksLenght)
                {
                    this.ticksLenght = value;
                    base.InvalidateStatic();
                }
            }
        }

        public SliderElementsPosition TicksPosition
        {
            get
            {
                return this.ticksPosition;
            }
            set
            {
                if (value == SliderElementsPosition.Internal)
                {
                    value = SliderElementsPosition.Both;
                }
                if (this.ticksPosition != value)
                {
                    this.ticksPosition = value;
                    base.InvalidateStatic();
                }
            }
        }

        public Color ValueBackgroundColor
        {
            get
            {
                return this.valueBackgroundColor;
            }
            set
            {
                if (this.valueBackgroundColor != value)
                {
                    this.valueBackgroundColor = value;
                    base.InvalidateStatic();
                }
            }
        }

        public SliderElementsPosition ValuePosition
        {
            get
            {
                return this.valuePosition;
            }
            set
            {
                if (this.valuePosition != value)
                {
                    this.valuePosition = value;
                    base.InvalidateStatic();
                }
            }
        }
    }
}

